package schedulingAlgorithm.genetic;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 亚明生产车间调度算法实例
 *
 * @author lin
 * @Date 2020.3.6
 */
public class Run {
    public static void main(String[] args) {
        System.out.println("开始执行！");
        // 程序运行开始时间
        Date startTime = new Date();
        // 创建遗传集合结构体
        GeneticModel geneticModel = new GeneticModel();
        // 设置生产基本信息
        // 每行为一个工单
        // 每个list的内容为工序，[0]为工位编号， [1]为加工耗时
        List<List<Integer[]>> job = Arrays.asList(
                Arrays.asList(new Integer[]{0, 10}, new Integer[]{1, 15}, new Integer[]{2, 50}, new Integer[]{3, 30}, new Integer[]{4, 20}),
                Arrays.asList(new Integer[]{0, 10}, new Integer[]{1, 15}, new Integer[]{2, 50}, new Integer[]{3, 30}, new Integer[]{4, 20}),
                Arrays.asList(new Integer[]{1, 15}, new Integer[]{4, 20}, new Integer[]{0, 60}, new Integer[]{3, 50}, new Integer[]{2, 40})
        );
        //取出所有工位
        List<Integer> firstNumbers = new ArrayList<>();
        for (List<Integer[]> sublist : job) {
            for (Integer[] pair : sublist) {
                firstNumbers.add(pair[0]);
            }
        }
        firstNumbers = firstNumbers.stream().distinct().collect(Collectors.toList());
        Map<Integer, Integer[]> stationList = new HashMap<>();
        stationList.put(0, new Integer[]{0, 24});
        stationList.put(1, new Integer[]{0, 24});
        stationList.put(2, new Integer[]{0, 24});
        stationList.put(3, new Integer[]{0, 24});
        stationList.put(4, new Integer[]{0, 24});

        //初始化工位的工作时长和初始值
        geneticModel.stationList.putAll(stationList);
        // 设定初始工位数量和工单数量
        int workOrderNum = job.size(), stationNum = stationList.size();
        // 初始化遗传算法
        GeneticAlgorithm gene = new GeneticAlgorithm(geneticModel, workOrderNum, stationNum);
        // 计算当前工序和工位生产关系的最优解
        int minTime = GeneticAlgorithm.optimalSolution(geneticModel, job, firstNumbers);
        // 输出最优解
        System.out.println("最优解总耗时：" + minTime);
        System.out.println("目前遗传代数：" + geneticModel.populationNumber);
        // 开始计算
        Result result = gene.run(geneticModel, job, minTime);
        // 获取程序计算出来的最优解
        int[][] machineMatrix = geneticModel.stationMatrix;
        // 输出程序计算出来的最优解
        System.out.println("计算最优总耗时：" + result.fulfillTime);

        // 输出结果，结果格式自行调整
        for (int i = 0; i < workOrderNum; i++) {
            for (int j = 0; j < geneticModel.processNumber; j++) {
                if (machineMatrix[i][j] != -1) {
                    System.out.printf("工单: %d, 工序: %d, 工位: %d, 开始时间: %d, 结束时间: %d%n",
                            i + 1, j + 1, machineMatrix[i][j] + 1, result.startTime[i][j], result.endTime[i][j]);
                }
            }
        }
        System.out.println("算法结束！");
        System.out.println("程序用时：" + (new Date().getTime() - startTime.getTime()) / 1000);
    }
}
